package org.wheel.plugins.toolkit.util.bean;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import lombok.Getter;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class DataHandlerUtil {

    // 设置单例模式
    @Getter
    private static final DataHandlerUtil instance = new DataHandlerUtil();
    private DataHandlerUtil() {
    }

    // 分组时，给内部设置唯一的id key值
    private final static String serialVersionUIDKey = "serialVersionUID";

    /**
     * 入口函数 1 buildDynamicObject
     * 构建动态对象集合，将SQL查询结果转换为动态对象集合。数据库字段名按驼峰式命名
     * @param list SQL查询结果集合
     * @return 动态对象
     */
    public List<DynaBean> buildDynamicObject(List<Map<String, Object>> list) {
        return buildDynamicObject(list, StrUtil::toCamelCase, (k, v)->this.defaultValue(v));
    }

    /** 入口函数 2 buildDynamicObjectGroup */
    public List<DynaBean> buildDynamicObjectGroup(List<Map<String, Object>> list){
        return buildDynamicObjectGroup(buildDynamicObject(list), null);
    }

    /**
     * * 构建动态对象，将SQL查询结果转换为动态对象。
     * @param list SQL查询结果集合
     * @param propertyNamingStrategy 属性命名策略，传入数据库字段名，返回一个属性名的值，可以将这个属性名转换为小写、大写、驼峰式等，或者根据业务需求进行转换定义
     * @return 动态对象集合
     */
    public List<DynaBean> buildDynamicObject(List<Map<String, Object>> list, Function<String, String> propertyNamingStrategy) {
        return buildDynamicObject(list, propertyNamingStrategy, (k, v)->this.defaultValue(v));
    }

    public List<DynaBean> buildDynamicObject(List<Map<String, Object>> list, BiFunction<String, Object, Object> valueStategy) {
        return buildDynamicObject(list, StrUtil::toCamelCase, valueStategy);
    }

    /**
     * * 构建动态对象，将SQL查询结果转换为动态对象。
     * @param list SQL查询结果集合
     * @param propertyNamingStrategy 属性命名策略，传入数据库字段名，返回一个属性名的值，可以将这个属性名转换为小写、大写、驼峰式等，或者根据业务需求进行转换定义
     * @param valueStategy 值转换策略，传入列值，返回一个值，可以对值进行转换，例如：将null值转换为""
     * @return 动态对象
     */
    public List<DynaBean> buildDynamicObject(List<Map<String, Object>> list, Function<String, String> propertyNamingStrategy, BiFunction<String, Object, Object> valueStategy) {
        return list.stream().map(map->buildDynamicObject(map, propertyNamingStrategy, valueStategy)).toList();
    }

    /**
     * 构建动态对象，将SQL查询结果转换为动态对象。
     * @param row SQL查询结果单行对象
     * @param propertyNamingStrategy 属性命名策略，传入数据库字段名，返回一个属性名的值，可以将这个属性名转换为小写、大写、驼峰式等，或者根据业务需求进行转换定义
     * @param valueStategy 值转换策略，传入列值，返回一个值，可以对值进行转换，例如：将null值转换为""
     * @return 动态对象
     */
    public DynaBean buildDynamic(Map<String, Object> row, Function<String, String> propertyNamingStrategy, BiFunction<String, Object, Object> valueStategy) {
        return buildDynamicObject(row, propertyNamingStrategy, valueStategy);
    }

    /*
     *  分组处理
     */
    //================================================================================================================================

    public List<LinkedHashMap<String, Object>> restore(List<DynaBean> list) {
        return list.stream().map(o-> restoreDynaBean(o, true)).toList();
    }

    /**
     * 默认的值处理策略
     * @param value 值
     * @return 处理后的值
     */
    public Object defaultValue(Object value) {
        if (value == null) {
            return null;
        } else if (value instanceof String val) {
            return val;
        }
        else if (value instanceof  Integer val) {
            return val;
        }
        else if (value instanceof Long val) {
            return val;
        }
        else if (value instanceof  Double val) {
            return val;
        }
        else if (value instanceof  Float val) {
            return val;
        }
        else if (value instanceof Boolean val) {
            return val;
        }
        else if (value instanceof Date val) {
            return DateUtil.format(val, DatePattern.NORM_DATETIME_PATTERN);
        } else if (value instanceof LocalDateTime val) {
            return val.format(DatePattern.NORM_DATETIME_FORMATTER);
        }else if (value instanceof LocalDate val) {
            return val.format(DatePattern.NORM_DATE_FORMATTER);
        }else if(value instanceof Instant){
            return DateUtil.format(LocalDateTime.from(Instant.ofEpochMilli(((Instant)value).toEpochMilli())), DatePattern.NORM_DATETIME_PATTERN);
        }
        return value;
    }

    // 还原处理
    public List<LinkedHashMap<String, Object>> restore(List<DynaBean> list, boolean ignoreNull) {
        return list.stream().map(o-> restoreDynaBean(o, ignoreNull)).toList();
    }

    /**
     * 递归还原处理
     * @param bean DynaBean对象
     * @param ignoreNull 是否忽略空值
     * @return 将数据对象转换为map对象
     */
    public LinkedHashMap<String, Object> restoreDynaBean(DynaBean bean, boolean ignoreNull){
        LinkedHashMap<String, Object> tmp = new LinkedHashMap<>();
        ((LinkedHashMap<String, Object>)bean.getBean()).keySet().forEach(k->{
            Object tmpObj = bean.get(k);
            if(tmpObj instanceof DynaBean sub){
                tmp.put(k, restoreDynaBean(sub, ignoreNull));
            }else if(tmpObj instanceof List<?> list){
                tmp.put(k,list.stream().map(tmpSub->restoreDynaBean((DynaBean)tmpSub, ignoreNull)).toList());
            }else{
                if(ignoreNull){
                    if(tmpObj != null){
                        tmp.put(k, tmpObj);
                    }
                }else{
                    tmp.put(k, tmpObj);
                }
            }
        });
        return tmp;
    }

    /**
     * 分组处理
     * @param dynaBeanList 数据集
     * @param isCollection 属性对应的值，如果合并后，是集合对象，需要外部介入，判断是否是集合，默认是不处理，如果是集合就返回集合对象
     * @return 最终对象
     */
    public List<DynaBean> buildDynamicObjectGroup(List<DynaBean> dynaBeanList, Predicate<String> isCollection) {
        Map<String, List<DynaBean>> groupedByProperty = buildGroupedByUIDKey(dynaBeanList);

        return groupedByProperty.values().stream()
                .map(o->mergedData(o, isCollection))
                .peek(this::removeChildBeanUIDKey)
                .toList();
    }

    /**
     * 合并处理
     * @param resultSet 结果集
     * @param isCollection 属性对应的值，如果合并后，是集合对象，需要外部介入，判断是否是集合，默认是不处理，如果是集合就返回集合对象
     * @return 最终对象
     */
//    public DynaBean mergedData(List<DynaBean> resultSet, Predicate<String> isCollection) {
//        DynaBean mergedBean = DynaBean.create(LinkedHashMap.class);
//        Map<String, List<DynaBean>> subBeanMap = new LinkedHashMap<>();
//        resultSet.forEach(bean->{
//            ((LinkedHashMap<String, Object>)bean.getBean()).keySet().forEach(k->{
//                Object v = bean.get(k);
//                if(v instanceof DynaBean sub){
//                    subBeanMap.computeIfAbsent(k, val -> new ArrayList<>()).add(sub);
//                }else{
//                    mergedBean.set(k, v);
//                }
//            });
//        });
//        if(MapUtil.isNotEmpty(subBeanMap)){
//            subBeanMap.forEach((k, v) -> {
//                if(isCollection != null){
//                    if(isCollection.test(k)){
//                        mergedBean.set(k, buildDynamicObjectGroup(v, isCollection));
//                    }else{
//                        List<DynaBean> list = buildDynamicObjectGroup(v, isCollection);
//                        if(list.stream().allMatch(o->o.containsKey(serialVersionUIDKey))){
//                            list = CollUtil.distinct(list, o->o.get(serialVersionUIDKey).toString(), false);
//                        }
//                        mergedBean.set(k, CollectionUtil.isNotEmpty(list) ? (list.size() > 1 ? list : list.get(0)) : null);
//                    }
//                }else {
//                    mergedBean.set(k, buildDynamicObjectGroup(v, null));
//                }
//            });
//        }
//        return mergedBean;
//    }

    /**
     * 合并处理（支持完整嵌套路径传入 isCollection 判断）
     *
     * @param resultSet  结果集
     * @param isCollection 判断函数，接收完整嵌套路径，如 "company.address.streets"
     * @return 最终对象
     */
    public DynaBean mergedData(List<DynaBean> resultSet, Predicate<String> isCollection) {
        return mergedData(resultSet, isCollection, ""); // 根路径为空
    }

    /**
     * 内部递归方法，支持路径前缀
     *
     * @param resultSet   结果集
     * @param isCollection 判断函数
     * @param pathPrefix  当前路径前缀，如 "company.address."
     * @return 合并后的 DynaBean
     */
    private DynaBean mergedData(List<DynaBean> resultSet, Predicate<String> isCollection, String pathPrefix) {
        DynaBean mergedBean = DynaBean.create(LinkedHashMap.class);
        Map<String, List<DynaBean>> subBeanMap = new LinkedHashMap<>();

        for (DynaBean bean : resultSet) {
            LinkedHashMap<String, Object> map = bean.getBean();
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();

                String fullKey = pathPrefix + key; // 完整路径，如 "company.address"

                if (value instanceof DynaBean sub) {
                    subBeanMap.computeIfAbsent(key, k -> new ArrayList<>()).add(sub);
                } else {
                    mergedBean.set(key, value);
                }
            }
        }

        if (MapUtil.isNotEmpty(subBeanMap)) {
            for (Map.Entry<String, List<DynaBean>> entry : subBeanMap.entrySet()) {
                String key = entry.getKey();
                String fullKey = pathPrefix + key; // 完整路径
                List<DynaBean> subList = entry.getValue();

                boolean isColl = isCollection != null && isCollection.test(fullKey);

                if (isColl) {
                    // 是集合：递归合并每个子项，最终返回 List<DynaBean>
                    List<DynaBean> mergedSubList = new ArrayList<>();
                    for (DynaBean sub : subList) {
                        DynaBean mergedSub = mergedData(List.of(sub), isCollection, fullKey + ".");
                        mergedSubList.add(mergedSub);
                    }
                    mergedBean.set(key, mergedSubList);
                } else {
                    // 是对象：合并为一个
                    DynaBean mergedSub = mergedData(subList, isCollection, fullKey + ".");
                    mergedBean.set(key, mergedSub);
                }
            }
        }

        return mergedBean;
    }

    /**
     * 移除子Bean中的UID键值
     * @param bean 数据对象
     */
    public void removeUIDKey(DynaBean bean){
        revmove(bean, serialVersionUIDKey);
    }

    /**
     * 递归移除子Bean中的键值
     * @param bean 数据对象
     * @param key 移除的键值
     */
    public void revmove(DynaBean bean, String key){
        bean.invoke("remove", key);
    }

    /**
     * 按照属性进行分组
     * @param dynaBeanList 数据集
     * @return 分组结果
     */
    public Map<String, List<DynaBean>> buildGroupedByUIDKey(List<DynaBean> dynaBeanList) {
        // 按照属性进行分组，例如按照属性 "groupName" 进行分组
//        return dynaBeanList.stream()
//                .collect(Collectors.groupingBy(bean -> bean.get(serialVersionUIDKey)));
        // 按照数据先后顺序进行分组
        return dynaBeanList.stream()
                .collect(Collectors.groupingBy(
                        // 分类函数
                        bean -> (String)bean.get(serialVersionUIDKey),
                        // 使用 LinkedHashMap 保持顺序
                        LinkedHashMap::new,
                        // 合并同一组的元素
                        Collectors.toList()
                ));
    }


    /**
     * 递归移除子Bean中的UID键值
     * @param dynaBean 单条数据bean对象
     */
    public void removeChildBeanUIDKey(DynaBean dynaBean){
        if(dynaBean == null) {
            return;
        }
        removeUIDKey(dynaBean);
        LinkedHashMap<String, Object> map = dynaBean.getBean();
        map.values().stream().filter(o -> (o instanceof DynaBean))
                .peek(o->removeUIDKey((DynaBean)o))
                .filter(o->allContains((DynaBean)o, serialVersionUIDKey))
                .forEach(o->removeChildBeanUIDKey((DynaBean)o));
        map.values().stream().filter(o->(o instanceof Collection))
                .forEach(o->((List<DynaBean>)o).forEach(this::removeChildBeanUIDKey));
    }

    /*
     * 以下是辅助方法，将数据插入唯一键值，便于后续分组处理
     */
    //================================================================================================================================
    /**
     * <pre>
     * 构建动态对象，将SQL查询结果转换为动态对象。
     * 传入的参数，其中每一行数据都是一个Map对象
     * 对象中，key是列名，value是列值。
     * 列名可以包含多级嵌套，例如：a.b.c等，
     * 如果别名是 A.B 说明这个数据是A对象下的B属性值。
     *
     * 例如：
     * SQL： select id, person_name as "vbean.personName" from table
     * row： {id=1, vbean={personname=张三}}
     *</pre>
     * @param row SQL查询结果单行对象
     * @param propertyNamingStrategy 属性命名策略，自定义属性命名，可以将列名转换为驼峰命名，下划线命名等。如果不传，默认使用数据库的列名。
     * @param valueStategy 值转换策略，用于将数据库查询结果转换为Java对象，包括但不限于：数值转换，日期转换等。例如：数据库查询结果为String，Java对象为Integer，需要转换为Integer类型
     *                     传入：key, value, 返回：value
     * @return 动态对象
     */
    public DynaBean buildDynamicObject(Map<String, Object> row, Function<String, String> propertyNamingStrategy, BiFunction<String, Object, Object> valueStategy){
        // 保存当前对象的属性值，用于后续设置serialVersionUID
        Map<String, String> keys = new HashMap<>();
        // 构建动态对象
        DynaBean dynaBean = DynaBean.create(LinkedHashMap.class);
        row.forEach((columnName, value) -> {
            // 解析列名，构建嵌套结构
            String[] nestedProperties = columnName.split("\\.");
            DynaBean currentBean = dynaBean;
            for (int i = 0; i < nestedProperties.length - 1; i++) {
                String propertyName = nestedProperties[i];

                // 保存当前对象的属性值，用于后续设置serialVersionUID
                keys.put(propertyName, "");

                DynaBean nextBean = (DynaBean)currentBean.get(propertyName);
                if (nextBean == null) {
                    nextBean = DynaBean.create(LinkedHashMap.class);
                    currentBean.set(propertyName, nextBean);
                }
                currentBean = nextBean;
            }

            // 设置最终属性值
            String finalPropertyName = nestedProperties[nestedProperties.length - 1];
            if (propertyNamingStrategy!= null) {
                finalPropertyName = propertyNamingStrategy.apply(finalPropertyName);
            }
            if(valueStategy!= null){
                value = valueStategy.apply(finalPropertyName, value);
            }

            currentBean.set(finalPropertyName, value);
        });

        // 循环设置serialVersionUID
        keys.keySet().forEach(key -> getPropOne(dynaBean, key));
        setSerialVersionUIDKey(dynaBean);
//        if(dynaBean.values().stream().allMatch(ObjectUtil::isEmpty)){
//            return null;
//        }
        return dynaBean;
    }


    /**
     * 为单个bean设置serialVersionUID
     * @param dynaBean 子bean
     * @param key bean的key
     */
    public void getPropOne(DynaBean dynaBean, String key){
        if(dynaBean!= null && dynaBean.values().stream().anyMatch(ObjectUtil::isNotEmpty) && allContains(dynaBean, key)) {
            if(dynaBean.containsProp(key)){
                DynaBean child = (DynaBean)dynaBean.get(key);
                if(child!= null && child.values().stream().anyMatch(ObjectUtil::isNotEmpty) && !child.containsProp(serialVersionUIDKey)){
                    setSerialVersionUIDKey(child);
                }else if(child!= null && child.values().stream().allMatch(ObjectUtil::isEmpty)){
                    revmove(dynaBean, key);
                }
            }else{
                DynaBean child = getChildBean(dynaBean, key);
                if(child!= null){
                    if(child.values().stream().anyMatch(ObjectUtil::isNotEmpty)) {
                        setSerialVersionUIDKey(child);
                    }else{
                        setChildBean(dynaBean, key, null);
                    }
                }
            }
        }
    }

    /**
     * 判断是否有子DynaBean
     * @param dynaBean 父bean
     * @return 是否有子DynaBean
     */
    public boolean hasChildDynaBean(DynaBean dynaBean){
        return ((LinkedHashMap<String, Object>)dynaBean.getBean()).values().stream().anyMatch(o -> (o instanceof DynaBean));
    }
    /**
     * 剔除掉所有DynaBean的LinkedHashMap对象，剩下的字符串就是当前bean的内部属性值。
     * 内部翻出的时候，通过key排序，保证获取的UID一致
     * @param dynaBean 父bean
     * @return key键值，明文字符串
     */
    public String getSelfProp(DynaBean dynaBean) {
        if(dynaBean == null){
            return null;
        }
        if(hasChildDynaBean(dynaBean)) {
            // 深度拷贝dynaBean
//            DynaBean cp = SerializationUtils.clone(dynaBean);
            // Hutool 5.7.0+版本提供了更智能的克隆方法  ObjectUtil.clone
            DynaBean cp = ObjectUtil.cloneByStream(dynaBean);
            LinkedHashMap<String, Object> map = cp.getBean();
            LinkedHashMap<String, Object> jsonMap = new LinkedHashMap<>(map);
            jsonMap.forEach((k, v) -> {
                if (cp.get(k) instanceof DynaBean) {
                    map.remove(k);
                }
            });
            return cp.toString();
        }
        return dynaBean.toString();
    }

    /**
     * 根据key获取子bean
     * @param dynaBean 父bean
     * @param key 键值
     * @return 子bean
     */
    public DynaBean getChildBean(DynaBean dynaBean, String key){
        if(dynaBean!= null && allContains(dynaBean, key)) {
            LinkedHashMap<String, Object> map = dynaBean.getBean();
            if(map.containsKey(key)){
                return (DynaBean)map.get(key);
            }else{
                return map.values().stream()
                        .filter(o -> (o instanceof DynaBean))
                        .map(o -> getChildBean((DynaBean) o, key))
                        .filter(Objects::nonNull)
                        .findFirst().orElse(null);
            }
        }
        return null;
    }

    /**
     * 设置子bean
     * @param dynaBean
     * @param key
     * @param child
     */
    public void setChildBean(DynaBean dynaBean, String key, DynaBean child){
        if(dynaBean.containsKey(key)){
            dynaBean.set(key, child);
        }else{
            dynaBean.getBean().values().stream()
                    .filter(o -> (o instanceof DynaBean))
                    .forEach(o -> setChildBean((DynaBean) o, key, child));
        }
    }

    /**
     * 为单个bean设置serialVersionUID
     * @param dynaBean 子bean
     */
    public void setSerialVersionUIDKey(DynaBean dynaBean){
        if(dynaBean!= null && dynaBean.values().stream().anyMatch(ObjectUtil::isNotEmpty) &&!dynaBean.containsProp(serialVersionUIDKey)) {
            String json = getSelfProp(dynaBean);
            String uidKey = DigestUtil.sha256Hex(json);
            dynaBean.set(serialVersionUIDKey, uidKey);
        }
    }

    public static boolean allContains(DynaBean dynaBean, String key){
        return dynaBean.toString().contains(key);
    }

    //================================================================================================================================

    /**
     * 解析类结构，提取字段类型信息（支持集合、嵌套对象）
     * 支持泛型集合：如 List<Order> -> elementType = Order.class
     *
     * @param clazz 目标类
     * @return 字段名 -> 类型信息映射
     */
    public static Map<String, FieldTypeInfo> parseClassStructure(Class<?> clazz) {
        return Arrays.stream(clazz.getDeclaredFields())
                .collect(Collectors.toMap(
                        Field::getName,
                        field -> {
                            Class<?> fieldType = field.getType();
                            boolean isCollection = Collection.class.isAssignableFrom(fieldType);

                            Class<?> elementType = null;
                            if (isCollection) {
                                // 获取泛型参数，如 List<Order> -> Order.class
                                Type genericType = field.getGenericType();
                                if (genericType instanceof ParameterizedType) {
                                    ParameterizedType pt = (ParameterizedType) genericType;
                                    Type actualType = pt.getActualTypeArguments()[0];
                                    if (actualType instanceof Class) {
                                        elementType = (Class<?>) actualType;
                                    }
                                }
                            } else if (!isPrimitiveOrWrapper(fieldType)) {
                                // 非集合、非基本类型 -> 认为是嵌套对象
                                elementType = fieldType;
                            }

                            return new FieldTypeInfo(isCollection, fieldType, elementType);
                        },
                        (a, b) -> a, // 重复字段名保留第一个
                        LinkedHashMap::new // 保持字段顺序
                ));
    }

    /**
     * 缓存类结构信息，避免重复解析
     * Key: 类类型，Value: 字段名 -> 字段类型信息
     */
//    private static final Map<Class<?>, Map<String, FieldTypeInfo>> CLASS_STRUCTURE_CACHE = new ConcurrentHashMap<>();
    /**
     * 获取类结构信息（带缓存）
     *
     * @param clazz 目标类
     * @return 字段名 -> 类型信息映射
     */
    public static Map<String, FieldTypeInfo> getClassStructure(Class<?> clazz) {
//        return CLASS_STRUCTURE_CACHE.computeIfAbsent(clazz, k -> parseClassStructure(k));
        return parseClassStructure(clazz); // 不再缓存
    }

    /**
     * 判断是否为基本类型或包装类型
     */
    private static boolean isPrimitiveOrWrapper(Class<?> clazz) {
        return clazz.isPrimitive() ||
                clazz == String.class ||
                clazz == Integer.class || clazz == int.class ||
                clazz == Long.class || clazz == long.class ||
                clazz == Double.class || clazz == double.class ||
                clazz == Float.class || clazz == float.class ||
                clazz == Boolean.class || clazz == boolean.class ||
                clazz == Short.class || clazz == short.class ||
                clazz == Byte.class || clazz == byte.class ||
                clazz == Character.class || clazz == char.class;
    }


    /**
     * 将 DynaBean 映射为目标类对象（支持嵌套对象、集合）
     * 入口方法
     *
     * @param dynaBean  源数据
     * @param targetClass 目标类类型
     * @param <T>       目标类型
     * @return 映射后的对象
     */
    public <T> T mapDynaBeanToObject(DynaBean dynaBean, Class<T> targetClass) {
        return mapDynaBeanToObject(dynaBean, targetClass, getClassStructure(targetClass));
    }

    /**
     * 批量映射 DynaBean 列表为目标对象列表
     */
    public <T> List<T> mapDynaBeanListToObjectList(List<DynaBean> dynaBeanList, Class<T> clazz) {
        if (CollUtil.isEmpty(dynaBeanList)) return Collections.emptyList();

        Map<String, FieldTypeInfo> typeInfoMap = getClassStructure(clazz);
        return dynaBeanList.stream()
                .map(dyna -> mapDynaBeanToObject(dyna, clazz, typeInfoMap))
                .collect(Collectors.toList());
    }

    /**
     * 批量映射 DynaBean 列表为目标对象列表（支持外部传入类结构信息）
     */
    public <T> List<T> mapDynaBeanListToObjectList(List<DynaBean> dynaBeanList, Class<T> clazz, Map<String, FieldTypeInfo> typeInfoMap) {
        if (CollUtil.isEmpty(dynaBeanList)) return Collections.emptyList();

        return dynaBeanList.stream()
                .map(dyna -> mapDynaBeanToObject(dyna, clazz, typeInfoMap))
                .collect(Collectors.toList());
    }

    /**
     * 核心递归映射方法
     *
     * @param dynaBean   源数据
     * @param clazz      目标类
     * @param typeInfoMap 字段类型信息（外部传入，支持缓存）
     * @param <T>        目标类型
     * @return 映射后的对象
     */
    @SuppressWarnings("unchecked")
    public <T> T mapDynaBeanToObject(DynaBean dynaBean, Class<T> clazz, Map<String, FieldTypeInfo> typeInfoMap) {
        try {
            T instance = clazz.getDeclaredConstructor().newInstance();

            for (var entry : typeInfoMap.entrySet()) {
                String fieldName = entry.getKey();
                FieldTypeInfo info = entry.getValue();

                Object rawValue = dynaBean.get(fieldName);
                if (rawValue == null) continue;

                if (info.isCollection) {
                    // 集合类型：支持 List<DynaBean> -> List<目标对象>
                    if (!(rawValue instanceof List)) continue;

                    List<DynaBean> dynaList = (List<DynaBean>) rawValue;
                    List<Object> mappedList = new ArrayList<>();

                    for (DynaBean item : dynaList) {
                        Object mappedItem = mapDynaBeanToObject(item, info.elementType, getClassStructure(info.elementType));
                        mappedList.add(mappedItem);
                    }

                    setFieldValue(instance, fieldName, mappedList);
                } else if (isPrimitiveOrWrapper(info.rawType)) {
                    // 基本类型：直接赋值
                    setFieldValue(instance, fieldName, convertValue(rawValue, info.rawType));
                } else {
                    // 嵌套对象：递归映射
                    if (!(rawValue instanceof DynaBean)) continue;

                    DynaBean nestedDyna = (DynaBean) rawValue;
                    Object nestedObj = mapDynaBeanToObject(nestedDyna, info.elementType, getClassStructure(info.elementType));
                    setFieldValue(instance, fieldName, nestedObj);
                }
            }

            return instance;
        } catch (Exception e) {
            throw new RuntimeException("映射 DynaBean 到 " + clazz.getName() + " 失败", e);
        }
    }

    /**
     * 设置字段值（支持私有字段）
     */
    private void setFieldValue(Object obj, String fieldName, Object value) {
        try {
            Field field = obj.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(obj, value);
        } catch (Exception e) {
            throw new RuntimeException("设置字段 " + fieldName + " 失败", e);
        }
    }

    /**
     * 类型转换（支持常见类型）
     */
    private Object convertValue(Object value, Class<?> targetType) {
        if (value == null || targetType.isAssignableFrom(value.getClass())) {
            return value;
        }

        // 简单类型转换（可扩展）
        if (targetType == String.class) {
            return value.toString();
        } else if (targetType == Integer.class || targetType == int.class) {
            return Integer.parseInt(value.toString());
        } else if (targetType == Long.class || targetType == long.class) {
            return Long.parseLong(value.toString());
        } else if (targetType == Double.class || targetType == double.class) {
            return Double.parseDouble(value.toString());
        } else if (targetType == Boolean.class || targetType == boolean.class) {
            return Boolean.parseBoolean(value.toString());
        }

        return value;
    }

    /**
     * 批量将 DynaBean 列表转为标准 JSON 结构列表
     */
    public List<Map<String, Object>> toStandardJsonList(List<DynaBean> dynaBeanList, Predicate<String> isCollection) {
        if (CollUtil.isEmpty(dynaBeanList)) return Collections.emptyList();
        return dynaBeanList.stream()
                .map(dyna -> toStandardJson(dyna, isCollection))
                .collect(Collectors.toList());
    }

    /**
     * 将 DynaBean 转换为标准嵌套 Map 结构（JSON 兼容）
     * 支持判断字段是对象还是集合，外部可直接用 Hutool 转对象
     *
     * @param dynaBean     源数据
     * @param isCollection 外部判断函数：字段名 -> 是否为集合
     * @return 标准嵌套 Map（可直接 JSONUtil.toBean）
     */
    public Map<String, Object> toStandardJson(DynaBean dynaBean, Predicate<String> isCollection) {
        Map<String, Object> result = new LinkedHashMap<>();
        if (dynaBean == null) return result;

        LinkedHashMap<String, Object> beanMap = dynaBean.getBean();
        for (Map.Entry<String, Object> entry : beanMap.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (value instanceof DynaBean sub) {
                // 判断是否为集合
                boolean collection = isCollection != null && isCollection.test(key);
                if (collection) {
                    // 如果是集合，包装成 List<Map>
                    result.put(key, List.of(toStandardJson(sub, isCollection)));
                } else {
                    // 否则是对象
                    result.put(key, toStandardJson(sub, isCollection));
                }
            } else if (value instanceof List<?> list) {
                // 已经是 List，递归处理内部 DynaBean
                List<Object> mappedList = new ArrayList<>();
                for (Object item : list) {
                    if (item instanceof DynaBean itemDyna) {
                        mappedList.add(toStandardJson(itemDyna, isCollection));
                    } else {
                        mappedList.add(item);
                    }
                }
                result.put(key, mappedList);
            } else {
                result.put(key, value);
            }
        }

        return result;
    }
}
